#include <stdio.h>
#include <pthread.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
typedef enum
{
	JOB_STATUS_INVALID,
	JOB_STATE_IDLE,
	JOB_STATE_RUNNING,
	JOB_STATE_SUSPENDED,
	JOB_STATE_DONE,
	JOB_STATUS_LAST_VALUE,
}JOB_STATE;

typedef enum
{
	CMD_STATUS_INVALID,
	CMD_PING,					/*No Arguments */
	CMD_SET_THREAD_POOL_SIZE, 	/*arg1 should be contain the pool size */
	CMD_GET_THREAD_POOL_SIZE,	/*No Arguments, but pipe_fd should be initialsed to send the response back */
	CMD_ADD_JOB,				/*arg1 is the timeout value, function should point to the function to be executed, arg argument to that function*/
	CMD_GET_JOB_STATUS,			/*arg1 should be the job id, pipe_fd should be set*/
	CMD_EXIT,					/*Close all threads*/
	CMD_STATUS_LAST_VALUE,
}COMMAND;

struct msg
{
	COMMAND cmd;

	/*Some argument for the cmd*/
	int arg1;
	int arg2;

	/*The function that should be passed for ADD job Command*/
	int (*function)(void *);
	void *fn_arg;
};


typedef struct job_info
{
	int 				jobId;
 	JOB_STATE			state;
	struct msg			msg;
	struct job_info		*next;
}*JOB_INFO;

typedef struct
{
	pthread_t 	    thread_id;
	int			    cmd_pipe_fd[2];
    int             response_pipe_fd[2];
	int			    current_job_id;
    JOB_STATE       state;
}WorkerThreads;

typedef struct
{
	int response_pipe_fd[2];
	int cmd_pipe_fd[2];
	int num_of_threads;

    int worker_list_size;
    WorkerThreads   **worker_list;
}ThreadPool_MasterControl;


int ThreadPool_Initialize(int num_of_threads);

int ThreadPool_Ping(void);
int ThreadPool_SetThreadPoolSize(int count);
int ThreadPool_GetThreadPoolSize(void);
int ThreadPool_Exit(void);
